home *** CD-ROM | disk | FTP | other *** search
- Subject: Notes from the trenches: FW_CStrings
- Sent: 7/24/96 12:22 PM
- Received: 7/24/96 12:31 PM
- From: Kirk Swenson, kswenson@keypress.com
- Reply-To: ODF Interest, ODF-Interest@CILabs.ORG
- To: OpenDoc Development Framework Discussion List, ODF-Interest@CILabs.
-
- Having just spent time debugging in the bowels of my part's and ODF's
- string-handling code, I thought I would share a few of the lessons I've
- learned for those that have not already made the journey. (ODF team: feel
- free to clarify anything I say unclearly or incorrectly.) What follows are
- my top ten things to remember about dealing with ODF's FW_CString classes,
- in RLO (Reverse Letterman Order):
-
- 1) Conditionally include <PRStrRep.h> while debugging.
-
- FW_CString relies on an opaque FW_SPrivStringRep structure which is not
- accessible by the debugger by default. While opaque structures may be a
- good thing in design, they're a royal pain when debugging. Including the
- above header file makes the structure of the opaque FW_SPrivStringRep
- available to the debugger.
-
- 2) Don't rely on the <PRStrRep.h> file for anything other than debugging.
-
- Wrapping the include inside #ifdef FW_DEBUG/#endif will help here, assuming
- that you occasionally build a release version of your code. ;-)
-
- 3) FW_ODITextParams fParams;
-
- This structure is part of the FW_SPrivStringRep and contains the actual
- pointer to the string data. There is a pointer to the start of the string
- data, a length word, and a capacity word indicating the total size of the
- buffer. This is how you figure out what the string actually holds in the
- debugger. Also noteworthy, the fTextStart, fTextByteLength, and
- fTextByteCapacity fields of fParams appear to be redundant with the
- _buffer, _length, and _maximum fields of the fText (ODIText) structure that
- is also contained within the FW_SPrivStringRep -- the only difference is
- that the fText fields include the text format word (discussed below) while
- the fParams fields do not.
-
- 4) The string data start at buffer[4].
-
- String buffers are allocated to be 4 bytes larger than the space required
- for the characters, because the first four bytes are a longword which
- represents the text format (ODITextFormat), and is required for
- interoperability with OpenDoc text-handling routines. For example, the
- buffer for a FW_CString32 is actually 36 bytes. According to the
- documentation, the only currently supported value for this word is
- kODTraditionalMacText, which has a value of 0. The pointer in fParams
- points to the actual start of the text, not of the buffer.
-
- 5) The size of the FW_SPrivStringRep structure is 40 bytes.
-
- If you have a lot of unique strings, particularly if they're generally
- small, this is a lot of overhead. As strings are reused, however, the
- overhead gets amortized across multiple strings. It would appear that this
- overhead could be reduced by removing the redundancy within the
- FW_SPrivStringRep, at the expense of requiring some additional pointer
- manipulations, but I may be missing something here.
-
- 6) The FW_SPrivStringRep structure is allocated on the heap.
-
- Unique FW_CStrings require two heap allocations (one for the
- FW_SPrivStringRep and one for the buffer), while unique bounded strings
- require one. Setting a string equal to another string, of course, will
- reuse the other's representation, and hence will require no heap
- allocations.
-
- 7) The size of a FW_CString is only 8 bytes.
-
- FW_CString is a very lightweight class, particularly when it can refer to
- other representations and doesn't have to allocate any storage of its own.
- This suggests that code that generally refers to other strings without
- changing them should use FW_CString rather than a bounded string.
-
- 8) Bounded strings don't necessarily keep their strings in their buffers.
-
- When debugging bounded strings (FW_CString32, FW_CString255), particularly
- without being able to look into the opaque FW_SPrivStringRep, it is
- tempting to believe that the string data should be in the static buffer
- allocated by the bounded string. Due to its reference-counting nature,
- however, a bounded string initialized from another string will refer to
- that other string's representation. It will only use its own buffer if it
- has to do so to store a unique string. You have to follow the pointer in
- fParams to find the string.
-
- 9) Bounded strings aren't limited to the size of their bounds.
-
- As suggested by the previous item, the buffer allocated by a bounded string
- is to be used if necessary or convenient, but there is no requirement that
- it be used. If a bounded string grows to be longer than 32 or 255, it's
- quite happy to re-allocate a larger buffer. So if you have one 33-byte
- string among many shorter strings, you don't have to worry about truncating
- the long string.
-
- 10) There is a bug in ODF's bounded string code.
-
- As detailed in my previous message, there is a bug in ODF R1 which rears
- its head when modifying a (unique) bounded string that has previously been
- assigned to another string. Using FW_CString instead of FW_CString32 or
- FW_CString255 is a workaround until there is a fix.
-
- Kirk Swenson
- Senior Software Engineer
- Key Curriculum Press
- kswenson@keypress.com
-
-
-